using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace SimplIDE
{
  public partial class SimplIDE : Form
  {
    FileTree tree;
    Options op;

    public SimplIDE()
    {
      InitializeComponent();
      tree = new FileTree();
      panelFileView.Controls.Add(tree);
      tree.ContextMenuStrip = this.fileTreeMenu;
      tree.ContextMenuStrip.Enabled = true;
      this.tree.ContextMenuStrip.Opening += new CancelEventHandler(this.menuStripOpen);
      this.tree.NodeMouseClick += new TreeNodeMouseClickEventHandler(this.tree_NodeMouseClick);
      closeProjectToolStripMenuItem1.Enabled = false;
      closeProjectToolStripMenuItem.Enabled = false;
      addNewFileToProjectToolStripMenuItem.Enabled = false;
      removeFileFromProjectToolStripMenuItem.Enabled = false;
      toolStripMenuItem1.Enabled = false;
      toolStripMenuItem2.Enabled = false;
      setPropertiesToolStripMenuItem.Enabled = false;
      buildOrCompileToolStripMenuItem.Enabled = false;
      //tree.AddTab("as_arrayobject.cpp", tabControl).Text = File.ReadAllText(@"c:\Dev\mPhone\thirdparty\angelscript\angelscript\source\as_arrayobject.cpp").Replace("\t", "  ");

      FileInfo fi = new FileInfo(Application.ExecutablePath);
      if (!File.Exists(fi.DirectoryName + @"\MinGW\bin\mingw32-c++.exe"))
      {
        MessageBox.Show("MinGW not found");
      }
      if (!File.Exists(fi.DirectoryName + @"\SyntaxHighlighterSettingsBlack.xml"))
      {
        MessageBox.Show("SyntaxHighlighterSettingsBlack.xml not found");
      }
    }

    private void newProjectToolStripMenuItem_Click(object sender, EventArgs e)
    {
      if (tree.LoadedProject)
      {
        CloseProject();
        if (tree.LoadedProject) // cancel
          return;
      }

      NewProjectForm newform = new NewProjectForm(tree);
      newform.ShowDialog();
      if (tree.LoadedProject)
      {
        filesToolStripMenuItem.DropDownItems[2].Enabled = true;
        addNewFileToProjectToolStripMenuItem.Enabled = true;
        removeFileFromProjectToolStripMenuItem.Enabled = true;
        closeProjectToolStripMenuItem.Enabled = true;
        closeProjectToolStripMenuItem1.Enabled = true;
        setPropertiesToolStripMenuItem.Enabled = true;
        toolStripMenuItem1.Enabled = true;
        toolStripMenuItem2.Enabled = true;
        buildOrCompileToolStripMenuItem.Enabled = true;
        listBox1.Items.Clear();

        if (tree.Nodes.Count > 0 && tree.Nodes[0].FirstNode != null)
          tree.SelectedNode = tree.Nodes[0].FirstNode;

        RichTextBox editor = tree.AddTab("main.cpp", tabControl);
        editor.TextChanged += new EventHandler(onCodeEditorTextChanged);

        op = new Options(tree.DirPath);
        op.Show();
        op.Hide();
      }
    }

    void onCodeEditorTextChanged(object sender, EventArgs e)
    {
      CodeEditor editor = sender as CodeEditor;
      string key = (editor == null ? "" : editor.Tag.ToString());
      SetTabModified(key, true);
    }

    void SetTabModified(string key, bool modified)
    {
      if (tabControl.TabPages.ContainsKey(key))
      {
        string text = tabControl.TabPages[key].Text.Replace(" *", "");
        tabControl.TabPages[key].Text = text + (modified ? " *" : "");
      }
    }

    private void menuStripOpen(object sender, CancelEventArgs e)
    {
      this.Tag = ((ContextMenuStrip)sender).SourceControl;
    }

    private void addNewFileToProjectToolStripMenuItem_Click(object sender, EventArgs e)
    {
      if (this.Tag == tree)
      {
        NewFileForm newform = new NewFileForm(tree);
        newform.ShowDialog();
        if (newform.Made)
          tree.AddTab(newform.FileName, tabControl).TextChanged += onCodeEditorTextChanged;
      }
    }

    private void exitSimpleIDEToolStripMenuItem_Click(object sender, EventArgs e)
    {
      Application.Exit();
    }

    private void removeFileFromProjectToolStripMenuItem_Click(object sender, EventArgs e)
    {        
      string toRemove = this.tree.SelectedNode.Text;
      tree.RemoveFile();
      tabControl.Controls.RemoveByKey(toRemove);
    }

    private void closeProjectToolStripMenuItem_Click(object sender, EventArgs e)
    {
      if (this.Tag == tree)
        CloseProject();
    }

    public void CloseProject()
    {
      if (!tree.LoadedProject)
        return;
      if (tree.IsAnyFileModified(tabControl))
      {
        string msg = "Some files has been modified.\nDo you want to save them, before closing the project?";
        DialogResult result = MessageBox.Show(msg, "Warning", MessageBoxButtons.YesNoCancel);
        if (result == DialogResult.Yes)
        {
          tree.SaveAll(tabControl);
          foreach (TabPage tab in tabControl.TabPages)
            SetTabModified(tab.Name, false);
        }
        else if (result == DialogResult.Cancel)
          return;
      }
      tree.CloseFileTreeContent();
      filesToolStripMenuItem.DropDownItems[2].Enabled = false;
      addNewFileToProjectToolStripMenuItem.Enabled = false;
      removeFileFromProjectToolStripMenuItem.Enabled = false;
      closeProjectToolStripMenuItem.Enabled = false;
      closeProjectToolStripMenuItem1.Enabled = false;
      setPropertiesToolStripMenuItem.Enabled = false;
      buildOrCompileToolStripMenuItem.Enabled = false;
      toolStripMenuItem1.Enabled = false;
      toolStripMenuItem2.Enabled = false;
      listBox1.Items.Clear();
      this.tabControl.Controls.Clear();
    }

    private void closeProjectToolStripMenuItem1_Click(object sender, EventArgs e)
    {
      CloseProject();
    }



    private void setPropertiesToolStripMenuItem_Click(object sender, EventArgs e)
    {
      op.ShowDialog();
    }

    private void openProjectToolStripMenuItem_Click(object sender, EventArgs e)
    {
      if (tree.LoadedProject)
        CloseProject();

      openFileDialog.InitialDirectory = Directory.GetCurrentDirectory();
      if (openFileDialog.ShowDialog() == DialogResult.OK)
      {
        tree.OpenProject(openFileDialog.FileName, this.tabControl, onCodeEditorTextChanged);

        addNewFileToProjectToolStripMenuItem.Enabled = true;
        removeFileFromProjectToolStripMenuItem.Enabled = true;
        closeProjectToolStripMenuItem.Enabled = true;
        closeProjectToolStripMenuItem1.Enabled = true;
        setPropertiesToolStripMenuItem.Enabled = true;
        toolStripMenuItem1.Enabled = true;
        toolStripMenuItem2.Enabled = true;
        buildOrCompileToolStripMenuItem.Enabled = true;
        listBox1.Items.Clear();
        op = new Options(tree.DirPath);
        op.Show();
        op.Hide();
      }
    }
    private void tree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
    {
      string file = e.Node.Text;
      if (e.Node != null && this.tabControl.TabPages.ContainsKey(file))
        this.tabControl.SelectTab(file);
    }

    private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (tabControl.SelectedTab != null) tree.SelectFile(tabControl.SelectedTab.Name);
    }

    private void toolStripMenuItem1_Click(object sender, EventArgs e)
    {
      if (tree.SelectedNode != null && tree.SelectedNode != tree.Nodes[0])
      {
        tree.SaveFile(this.tabControl.Controls[tree.SelectedNode.Text].Controls[0].Text);
        SetTabModified(tree.SelectedNode.Name, false);
      }
    }

    private void toolStripMenuItem2_Click(object sender, EventArgs e)
    {
      tree.SaveAll(this.tabControl);
      foreach (TabPage tab in tabControl.TabPages)
        SetTabModified(tab.Name, false);
    }

    private void buildToolStripMenuItem_Click(object sender, EventArgs e)
    {
      foreach (TabPage tab in tabControl.TabPages)
        SetTabModified(tab.Name, false);
      BuildFunctions.Build(op, tabControl, listBox1, tree);
    }

    private void buildAllToolStripMenuItem_Click(object sender, EventArgs e)
    {
      foreach (TabPage tab in tabControl.TabPages)
        SetTabModified(tab.Name, false);
      BuildFunctions.BuildAll(op, tabControl, listBox1, tree);
    }

    private void runToolStripMenuItem_Click(object sender, EventArgs e)
    {
      string file;
      CheckBox cb = (CheckBox)op.panel1.Controls[6];
      if (cb.Checked)
      {
        file = tree.DirPath + @"\" + op.textBox3.Text;
      }
      else
      {
        file = tree.DirPath + @"\a.exe";
        if (!File.Exists(file))
          file = Path.GetFileName(file);
      }
      if (!File.Exists(file))
      {
        if (!BuildFunctions.Build(op, tabControl, listBox1, tree))
        {
          MessageBox.Show("Couldn't compile the project");
          return;
        }
      }

      System.Diagnostics.Process proc = new System.Diagnostics.Process();
      proc.EnableRaisingEvents = false;
      if (File.Exists(file))
        proc.StartInfo.FileName = file;
      else if (File.Exists(Path.GetFileName(file)))
        proc.StartInfo.FileName = Path.GetFileName(file);
      StreamReader sr = new StreamReader(tree.DirPath + @"\runoptions.txt");
      string sor;
      if ((sor = sr.ReadLine()) != null)
      {
        proc.StartInfo.Arguments = sor;
      }
      proc.Start();

    }

    private void listBox1_DoubleClick(object sender, EventArgs e)
    {
      if (listBox1.SelectedItem == null)
        return;
      string text = listBox1.SelectedItem.ToString();
      int i = text.IndexOf(".cpp:", StringComparison.OrdinalIgnoreCase);
      if (i == -1)
        return;
      string file = Path.GetFileName(text.Substring(0, i + 4));
      text = text.Substring(i + 5);
      text = text.Substring(0, text.IndexOf(":"));
      if (int.TryParse(text, out i))
      {
        if (tabControl.TabPages.ContainsKey(file))
          tabControl.SelectTab(file);
        RichTextBox t = this.tabControl.Controls[file].Controls[0] as RichTextBox;
        if (t != null)
        {
          t.Select(t.GetFirstCharIndexFromLine(Math.Max(0, i-1)), 0);
          t.Focus();
        }
      }
    }
  }
}